﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.IO;

using Historia.Data;
using Ionic.Zip;
using System.Windows.Media.Imaging;


namespace Historia
{
    public class DataManager
    {
        #region Constantes
        // Tables
        public const string DBINFO = "DBInfo";
        public const string PROJET = "Projet";
        public const string PERSONNAGES = "Personnages";
        public const string PERSONNAGES_SCENES = "Personnages_Scenes";
        public const string LIEUX = "Lieux";
        public const string LIEUX_SCENES = "Lieux_Scenes";
        public const string ITEMS = "Items";
        public const string ITEMS_SCENES = "Items_Scenes";
        public const string RECHERCHES = "Recherches";
        public const string FILS = "Fils";
        public const string FILS_SCENES = "Fils_Scenes";
        public const string CHAPITES = "Chapitres";
        public const string SCENES = "Scenes";

        // Répertoires
        public const string REPERTOIRE_IMAGE = "Images";
        #endregion

        #region Membres
        
        protected string _nomFichier = null;

        protected DataSet _db = null;

        #endregion

        #region Constructeurs

        /// <summary>
        /// Constructeur
        /// </summary>
        /// <param name="nomFichier">Nom du fichier à créer</param>
        public DataManager(string nomFichier) {

            this._nomFichier = nomFichier;
            //if (string.IsNullOrEmpty(nomFichier))
            //{
            //    this.CreerNouveauFichier();
            //}
            //else {
            //    this.OuvrirFichier(nomFichier);
            //}
            
        }

        #endregion

        #region Propriétés

        public string NomFichier {
            get { return this._nomFichier; }
        }

        #endregion

        public DataSet DB {
            get { return this._db; }
        }

        #region Méthodes

        /// <summary>
        /// Procédure qui crée un nouveau fichier
        /// </summary>
        public void CreerNouveauFichier() {
            //Un nouveau dataset
            this._db = new HistoriaDataSet();

            //On crée la version
            DataRow row = this._db.Tables[DBINFO].NewRow();
            row["version"] = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Revision;
            this._db.Tables[DBINFO].Rows.Add(row);
            this._db.Tables[DBINFO].AcceptChanges();

            //On crée le projet par défaut
            DataRow prj = this._db.Tables[PROJET].NewRow();
            prj["titre"] = this._nomFichier.Substring(this._nomFichier.LastIndexOf(Path.DirectorySeparatorChar)+1, (this._nomFichier.LastIndexOf(".") - this._nomFichier.LastIndexOf(Path.DirectorySeparatorChar))-1);
            prj["date_debut"] = DateTime.Now.Date;
            this._db.Tables[PROJET].Rows.Add(prj);
            this._db.Tables[PROJET].AcceptChanges();

            //On enregistre le fichier
            this.Enregistrer(this._nomFichier);

        }

        /// <summary>
        /// Fonction qui permet de sauvegarder un fichier
        /// </summary>
        /// <param name="nomFichier">nom du fichier à sauvegarder</param>
        /// <returns>bool</returns>
        public bool Enregistrer(String nomFichier){
            this._nomFichier = nomFichier;
            this._db.AcceptChanges();

            if (!System.IO.File.Exists(nomFichier))
            {
                using (ZipFile zip = new ZipFile())
                {
                    //TODO: Ajouter les images
                    using (MemoryStream ms = new MemoryStream())
                    {
                        this._db.WriteXml(ms, XmlWriteMode.WriteSchema);
                        ms.Flush();
                        ms.Position = 0;
                        zip.UpdateEntry("data.xml", ms);
                        zip.Save(nomFichier);

                        ms.Close();
                    }
                    
                }
            }
            else {
                using (ZipFile zip = ZipFile.Read(nomFichier))
                {
                    //TODO: Ajouter les images
                    using (MemoryStream ms = new MemoryStream())
                    {
                        this._db.WriteXml(ms, XmlWriteMode.WriteSchema);
                        ms.Flush();
                        ms.Position = 0;
                        zip.UpdateEntry("data.xml", ms);
                        zip.Save(nomFichier);

                        ms.Close();
                    }
                }
            }
        
            
            return true;
        }

        public void OuvrirFichier(string nomFichier) { 
            //_instance.CreerBackup(My.Application.Info.DirectoryPath + nomFichier)
            this._nomFichier = nomFichier;
            if (System.IO.File.Exists(this._nomFichier)) {
                MemoryStream ms = new MemoryStream();
                
                using(ZipFile zip = ZipFile.Read(this._nomFichier)){
                    ZipEntry e = zip["data.xml"];
                    e.Extract(ms);
                }

                ms.Position = 0;
                this._db = new DataSet();
                this._db.ReadXml(ms);
                ms.Close();
                this._db.AcceptChanges();

                //MAJBD
                //Dim version As Integer = _instance._db.Tables(DBINFO).Rows(0)("version")
                //_instance.MAJBaseDonnees(version)
            }
            else{
                //this.CreerNouveauFichier();
                //this.Enregistrer(this._nomFichier);
            }
        }

        public bool CopierFichier(string nomFichier, string ancienFichier,string newFileName)
        {
            try
            {
                if ((nomFichier != null) && (nomFichier.Length > 0))
                {
                    using (ZipFile zip = ZipFile.Read(this._nomFichier))
                    {
                        if (!string.IsNullOrEmpty(ancienFichier))
                        {
                            ZipEntry ancienneImage = zip["images\\" + ancienFichier];
                            if (!(ancienneImage == null))
                            {
                                zip.RemoveEntry("images\\" + ancienFichier);
                            }
                            
                        }
                        if (!string.IsNullOrEmpty(newFileName))
                        {
                            ZipEntry image = zip.AddFile(nomFichier, "images");
                            image.FileName = "images\\"+newFileName;
                        }
                        
                        zip.Save(_nomFichier);
                    }
                
                }

                return true;
            }
            catch (Exception ex)
            {

                return false;
            }
            
        }

        public bool RemoveFile(string fileName)
        {
            try
            {
                if ((fileName != null) && (fileName.Length > 0))
                {
                    using (ZipFile zip = ZipFile.Read(this._nomFichier))
                    {
                        if (!string.IsNullOrEmpty(fileName))
                        {
                            ZipEntry ancienneImage = zip["images\\" + fileName];
                            if (!(ancienneImage == null))
                            {
                                zip.RemoveEntry("images\\" + fileName);
                            }

                        }
                       zip.Save(_nomFichier);
                    }

                }

                return true;
            }
            catch (Exception ex)
            {

                return false;
            }

        }

        public BitmapImage GetImage(string fileName)
        {
            MemoryStream ms = new MemoryStream();
            using (ZipFile zip = ZipFile.Read(this._nomFichier))
            {
                ZipEntry image = zip["images\\"+fileName];
                image.Extract(ms);

                BitmapImage bi = new BitmapImage();
                ms.Position = 0;
                bi.BeginInit();
                bi.StreamSource = ms;
                bi.DecodePixelWidth = 200;
                bi.EndInit();
                bi.Freeze();
                return bi;
            }
        }
       

        #endregion
    }
}
